<template>
	<view>
		<view class="menuLeft">
			<view v-for="(item, index) in dataList" :key="index" @click="changeMenu(index)" :class="{ selectedMenu: index == clickIndex }">{{ item.title }}</view>
		</view>
		<view class="menuRight">
			<scroll-view scroll-y="true" style="height:100%;" :scroll-into-view="scrollIntoView" @scroll="onScroll">
				<view v-for="(item, index) in dataList" :key="index">
					<view style="background: red;" :id="'id' + index" class="category">{{ item.title }}</view>
					<view v-for="(ite, ind) in item.list" :key="ind" style="height:100rpx;">{{ ite }}</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<!-- 双联动菜单例子 -->
<script>
export default {
	data() {
		return {
			dataList: [
				{ title: '手机', list: ['iphone12', '华为p40', 'vivo90', 'oppoy77', '三星手机'] },
				{ title: '电脑', list: ['Mac pro', '联想yoga910', '华硕911', '联想811', '三星电脑'] },
				{ title: '水果', list: ['香蕉', '苹果', '西瓜', '榴莲', '山竹'] },
				{ title: '饮料', list: ['coke可乐', '脉动', '红牛', '冰糖雪梨', '果汁'] }
			],
			clickIndex: 0, // 切换class
			scrollIntoView: '', // scrollIntoView组件式通过id动态切换
			topList: [] // 所有节点的相对于scrollView的高度
		};
	},
	onLoad: function() {},
	methods: {
		// 切换菜单
		changeMenu(index) {
			this.clickIndex = index;
			this.scrollIntoView = 'id' + index; // 利用uniapp组件的配置信息。
			setTimeout(() => {
				this.clickIndex = index;
			}, 10)
		},
		onScroll(options) {
			// options为滚动信息, options.detail.scrollTop值为相对于scroll-view的高度。
			const query = uni.createSelectorQuery().in(this);
			query
				.selectAll('.category')
				.boundingClientRect(data => {
					this.topList = data.map(item => {
						return Math.ceil(item.top);
					});
					console.log('topList:', JSON.stringify(this.topList));
					this.syncLeftMenu(options);
				})
				.exec();
		},
		// 滑动的时同步左边菜单
		syncLeftMenu(options) {
			let topPage = options.detail.scrollTop + this.topList[0];
			for (let i = 0; i < this.topList.length; i++) {
				let node1 = this.topList[i];
				let node2 = this.topList[i + 1];
				if (node2 && topPage >= node1 && topPage < node2) {
					this.clickIndex = i;
					break;
				} else if (node2 && topPage === node2) {
					this.clickIndex = i + 1;
					break;
				}
			}
		},
	}
};
</script>

<style lang="scss" scoped>
.menuLeft,
.menuRight {
	display: inline-block;
	vertical-align: top;
	text-align: center;
	height: 700rpx;
	width: 200rpx;
}
.menuRight {
	display: inline-block;
	border: 1px solid #4cd964;
	width: 500rpx;
}
.selectedMenu {
	color: red;
}
</style>
